package controllers

import (
	"strings"

	"github.com/gin-gonic/gin"
	"jihe.common/protos/admin_auth_server"
	"jihe.common/protos/admin_auth_server/proto"
	"jihe.common/resp"
)

type AuthControoler struct {
}

func (s *AuthControoler) Login(c *gin.Context) {
	req := proto.AdminAuthUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespGeneralErr(c, "账号或密码错误")
		return
	}
	if req.Name == "" || req.Password == "" {
		resp.RespParamErr(c, "账号或密码错误")
		return
	}
	loginfo, err := admin_auth_server.AdminAuthLogin(c, &proto.AdminAuthUser{
		Name:     req.Name,
		Password: req.Password,
	})
	if err != nil {
		resp.RespGeneralErr(c, "账号或密码错误")
		return
	}
	if loginfo.Status != 1 {
		resp.RespGeneralErr(c, "账号已被禁用")
		return
	}
	tokenInfo, err := admin_auth_server.AdminAuthCreateToken(c, &proto.AdminAuthCreateTokenReq{
		Uid: loginfo.Id,
	})
	if err != nil {
		resp.RespInternalErr(c, "登录失败")
		return
	}

	userRoles, err := admin_auth_server.AdminAuthGetUserRole(c, &proto.AdminAuthGetUserRoleReq{
		Uid: loginfo.Id,
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	roleIds := make([]string, 0)
	for _, v := range userRoles.AdminAuthUserRoles {
		roleIds = append(roleIds, v.RoleId)
	}
	if len(roleIds) == 0 {
		resp.RespGeneralErr(c, "此账号未分配角色")
		return
	}
	roles, err := admin_auth_server.AdminAuthGetRoleByIds(c, &proto.AdminAuthGetRoleByIdsReq{
		RoleIds: strings.Join(roleIds, ","),
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	ret := make(map[string]interface{})
	ret["user"] = loginfo
	ret["secret"] = tokenInfo
	ret["role"] = roles
	resp.RespOk(c, ret)
}

func (s *AuthControoler) GetUserRole(c *gin.Context) {
	var uid string
	uid = c.Query("uid")
	if uid == "" {
		uid = getUid(c)
	}
	userRoles, err := admin_auth_server.AdminAuthGetUserRole(c, &proto.AdminAuthGetUserRoleReq{
		Uid: uid,
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	roleIds := make([]string, 0)
	for _, v := range userRoles.AdminAuthUserRoles {
		roleIds = append(roleIds, v.RoleId)
	}
	if len(roleIds) != 0 {
		roles, err := admin_auth_server.AdminAuthGetRoleByIds(c, &proto.AdminAuthGetRoleByIdsReq{
			RoleIds: strings.Join(roleIds, ","),
		})
		if err != nil {
			resp.RespInternalErr(c)
			return
		}
		resp.RespOk(c, roles.AdminAuthRoleList)
		return
	}
	resp.RespOk(c, make([]int, 0))
}

func (s *AuthControoler) Logout(c *gin.Context) {
	_, err := admin_auth_server.AdminAuthLogout(c, &proto.AdminAuthLogoutReq{
		Uid: getUid(c),
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c)
}

func (s *AuthControoler) DisabledUser(c *gin.Context) {
	action := c.Query("action")
	if action != "enable" && action != "disable" {
		resp.RespParamErr(c)
		return
	}
	uid := c.Query("uid")
	_, err := admin_auth_server.AdminAuthDisabledUser(c, &proto.AdminAuthDisabledUserReq{
		Uid:    uid,
		Action: action,
	})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c)
}

func (s *AuthControoler) CreateUser(c *gin.Context) {
	req := proto.AdminAuthUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Name == "" || req.Phone == "" {
		resp.RespParamErr(c)
		return
	}
	req.CreatedByUid = getUid(c)
	req.UpdatedByUid = getUid(c)
	ret, err := admin_auth_server.AdminAuthCreateUser(c, &req)
	if err != nil {
		if strings.Index(err.Error(), "user_name_unique") != -1 {
			resp.RespGeneralErr(c, "已有相同用户名")
			return
		}
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
	return
}

func (s *AuthControoler) UpdateUser(c *gin.Context) {
	req := proto.AdminAuthUser{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespParamErr(c)
		return
	}
	if req.Name == "" || req.Phone == "" || req.Id == "" {
		resp.RespParamErr(c)
		return
	}
	req.UpdatedByUid = getUid(c)
	_, err = admin_auth_server.AdminAuthUpdateUser(c, &req)
	if err != nil {
		if strings.Index(err.Error(), "user_name_unique") != -1 {
			resp.RespGeneralErr(c, "已有相同用户名")
			return
		}
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c)
	return
}

func (s *AuthControoler) ResetPassword(c *gin.Context) {
	uid := c.Query("uid")
	if uid == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := admin_auth_server.AdminAuthResetPassword(c, &proto.AdminAuthUser{
		Id:           uid,
		UpdatedByUid: getUid(c),
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
	return
}

func (s *AuthControoler) GiveUserRole(c *gin.Context) {
	uid := c.Query("uid")
	roleIds := c.Query("role_ids")
	if roleIds == "" {
		_, err := admin_auth_server.AdminAuthClearUserRole(c, &proto.AdminAuthUser{
			Id: uid,
		})
		if err != nil {
			resp.RespGeneralErr(c, err.Error())
			return
		}
		resp.RespOk(c)
		return
	}
	_, err := admin_auth_server.AdminAuthGiveUserRole(c, &proto.AdminAuthGiveUserRoleReq{
		Uid:     uid,
		RoleIds: roleIds,
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c)
	return
}

func (s *AuthControoler) GetUserList(c *gin.Context) {
	users, err := admin_auth_server.AdminAuthGetUserList(c, &proto.AdminAuthUser{})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	userMap := make(map[string]*proto.AdminAuthUser)
	for _, user := range users.AdminAuthUserList {
		userMap[user.Id] = user
	}
	ret := make([]map[string]interface{}, 0)
	for _, user := range users.AdminAuthUserList {
		itemMap := make(map[string]interface{})
		itemMap["user_info"] = user
		itemMap["updated_by_user"] = userMap[user.UpdatedByUid]
		itemMap["created_by_user"] = userMap[user.CreatedByUid]
		ret = append(ret, itemMap)
	}
	resp.RespOk(c, ret)
}

func (s *AuthControoler) GetUserPermission(c *gin.Context) {
	roleId := c.Query("role_id")
	if roleId == "" {
		resp.RespParamErr(c)
		return
	}
	userRoles, err := admin_auth_server.AdminAuthGetUserRole(c, &proto.AdminAuthGetUserRoleReq{
		Uid: getUid(c),
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}

	hasRole := false
	for _, v := range userRoles.AdminAuthUserRoles {
		if v.RoleId == roleId {
			hasRole = true
		}
	}
	if !hasRole {
		resp.RespGeneralErr(c, "此用户没有这个角色")
		return
	}
	permissions, err := admin_auth_server.AdminAuthGetPermissionsByRoleId(c, &proto.AdminAuthGetPermissionsByRoleIdReq{
		RoleId: roleId,
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}

	permissionsIds := make([]string, 0)
	for _, v := range permissions.AdminAuthRolePermissionList {
		permissionsIds = append(permissionsIds, v.PermissionId)
	}
	ret, err := admin_auth_server.AdminAuthGetPermissionsByIds(c, &proto.AdminAuthGetPermissionsByIdsReq{
		Ids: strings.Join(permissionsIds, ","),
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret.AdminAuthPermissionList)
}

func (s *AuthControoler) GetRoleList(c *gin.Context) {
	ret, err := admin_auth_server.AdminAuthGetRoleList(c, &proto.AdminAuthRole{})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret.AdminAuthRoleList)
}

func (s *AuthControoler) DeleteRole(c *gin.Context) {
	roleId := c.Query("role_id")
	if roleId == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := admin_auth_server.AdminAuthDeleteRole(c, &proto.AdminAuthDeleteRoleReq{
		Id: roleId,
	})
	if err != nil {
		if strings.Index(err.Error(), "errorno=1") != -1 {
			resp.RespGeneralErr(c, "该角色已被分配给用户，若要删除请先解除和用户的绑定关系")
			return
		}
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
}

func (s *AuthControoler) CreateRole(c *gin.Context) {
	req := proto.AdminAuthRole{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	if req.Name == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := admin_auth_server.AdminAuthCreateRole(c, &req)
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
}

func (s *AuthControoler) UpdateRole(c *gin.Context) {
	req := proto.AdminAuthRole{}
	err := c.BindJSON(&req)
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	if req.Name == "" || req.Id == "" {
		resp.RespParamErr(c)
		return
	}
	ret, err := admin_auth_server.AdminAuthUpdateRole(c, &req)
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret)
}

func (s *AuthControoler) GetPermissionListByRole(c *gin.Context) {
	roleId := c.Query("role_id")
	if roleId == "" {
		resp.RespParamErr(c)
		return
	}
	permissions, err := admin_auth_server.AdminAuthGetPermissionsByRoleId(c, &proto.AdminAuthGetPermissionsByRoleIdReq{
		RoleId: roleId,
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	permissionsIds := make([]string, 0)
	for _, v := range permissions.AdminAuthRolePermissionList {
		permissionsIds = append(permissionsIds, v.PermissionId)
	}
	ret, err := admin_auth_server.AdminAuthGetPermissionsByIds(c, &proto.AdminAuthGetPermissionsByIdsReq{
		Ids: strings.Join(permissionsIds, ","),
	})
	if err != nil {
		resp.RespGeneralErr(c, err.Error())
		return
	}
	resp.RespOk(c, ret.AdminAuthPermissionList)
}

func (s *AuthControoler) GiveRolePermission(c *gin.Context) {
	roleId := c.Query("role_id")
	if roleId == "" {
		resp.RespParamErr(c)
		return
	}
	permissionIds := c.Query("permission_ids")
	if permissionIds == "" {
		_, err := admin_auth_server.AdminAuthClearRolePermission(c, &proto.AdminAuthClearRolePermissionReq{
			RoleId: roleId,
		})
		if err != nil {
			resp.RespGeneralErr(c, err.Error())
			return
		}
		resp.RespOk(c)
		return
	}
	_, err := admin_auth_server.AdminAuthGiveRolePermission(c, &proto.AdminAuthGiveRolePermissionReq{
		RoleId:        roleId,
		PermissionIds: permissionIds,
	})
	if err != nil {
		resp.RespParamErr(c, err.Error())
		return
	}
	resp.RespOk(c)
	return
}

func (s *AuthControoler) GetPermissionList(c *gin.Context) {
	ret, err := admin_auth_server.AdminAuthGetPermissionList(c, &proto.AdminAuthGetPermissionListReq{})
	if err != nil {
		resp.RespInternalErr(c)
		return
	}
	resp.RespOk(c, ret.AdminAuthPermissionList)
	return
}
